--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
    local hy_tenkajin_chiyari = General:new(extension, "hy_tenkajin_chiyari", "jin_k", 4, 4, General.Female)
    local blood_fire = fk.CreateSkill {
        name = "blood_fire",
    }
    blood_fire:addEffect(fk.Damaged, {
        anim_type = "offensive",
        can_trigger = function(self, event, target, player, data)
            if not player:hasSkill(blood_fire.name) then
                return false
            end
            return target == player and table.any(player.room:getOtherPlayers(player), function(t)
                return #t:getCardIds("h") > 0
            end)
        end,
        on_cost = function(self, event, target, player, data)
            local room = player.room
            event:setCostData(self, table.map(room:askToChoosePlayers(player, {
                targets = table.filter(room:getOtherPlayers(player), function(t)
                    return #t:getCardIds("h") > 0
                end),
                min_num = 1,
                max_num = 1,
                prompt = "blood_fire_prompt",
                skill_name = blood_fire.name
            }), Util.IdMapper))
            return #event:getCostData(self) == 1
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local skillTarget = room:getPlayerById(event:getCostData(self)[1])
            local card = room:askToChooseCard(player, {
                target = skillTarget,
                flag = "h",
                skill_name = blood_fire.name
            })
            room:showCards(card, skillTarget)
            local choices = { "blood_fire_damage", "blood_fire_give" }
            local result = room:askToChoice(skillTarget, {
                choices = choices,
                skill_name = blood_fire.name,
                prompt = "blood_fire_prompt_choice"
            })
            if result == "blood_fire_give" then
                room:moveCardTo(card, Card.PlayerHand, player, fk.ReasonGive, blood_fire.name, nil, true, skillTarget)
            elseif result == "blood_fire_damage" then
                room:damage({
                    to = skillTarget,
                    damage = 1,
                    damageType = fk.FireDamage,
                    skillName = blood_fire.name
                })
                if not skillTarget.dead then
                    room:addPlayerMark(skillTarget, "@malice", 1)
                    room:recover({
                        who = skillTarget,
                        num = 1,
                        skillName = blood_fire.name
                    })
                end
            end
        end,
    })
    blood_fire:addEffect(fk.HpLost, {
        anim_type = "offensive",
        can_trigger = function(self, event, target, player, data)
            if not player:hasSkill(blood_fire.name) then
                return false
            end
            return target == player and table.any(player.room:getOtherPlayers(player), function(t)
                return #t:getCardIds("h") > 0
            end)
        end,
        on_cost = function(self, event, target, player, data)
            local room = player.room
            event:setCostData(self, table.map(room:askToChoosePlayers(player, {
                targets = table.filter(room:getOtherPlayers(player), function(t)
                    return #t:getCardIds("h") > 0
                end),
                min_num = 1,
                max_num = 1,
                prompt = "blood_fire_prompt",
                skill_name = blood_fire.name
            }), Util.IdMapper))
            return #event:getCostData(self) == 1
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local skillTarget = room:getPlayerById(event:getCostData(self)[1])
            local card = room:askToChooseCard(player, {
                target = skillTarget,
                flag = "h",
                skill_name = blood_fire.name
            })
            room:showCards(card, skillTarget)
            local choices = { "blood_fire_damage", "blood_fire_give" }
            local result = room:askToChoice(skillTarget, {
                choices = choices,
                skill_name = blood_fire.name,
                prompt = "blood_fire_prompt_choice"
            })
            if result == "blood_fire_give" then
                room:moveCardTo(card, Card.PlayerHand, player, fk.ReasonGive, blood_fire.name, nil, true, skillTarget)
            elseif result == "blood_fire_damage" then
                room:damage({
                    to = skillTarget,
                    damage = 1,
                    damageType = fk.FireDamage,
                    skillName = blood_fire.name
                })
                if not skillTarget.dead then
                    room:addPlayerMark(skillTarget, "@malice", 1)
                    room:recover({
                        who = skillTarget,
                        num = 1,
                        skillName = blood_fire.name
                    })
                end
            end
        end,
    })
    blood_fire:addEffect(fk.RoundEnd, {
        anim_type = "offensive",
        can_trigger = function(self, event, target, player, data)
            if not player:hasSkill(blood_fire.name) then
                return false
            end
            return table.any(player.room:getOtherPlayers(player), function(t)
                return #t:getCardIds("h") > 0
            end)
        end,
        on_cost = function(self, event, target, player, data)
            local room = player.room
            event:setCostData(self, table.map(room:askToChoosePlayers(player, {
                targets = table.filter(room:getOtherPlayers(player), function(t)
                    return #t:getCardIds("h") > 0
                end),
                min_num = 1,
                max_num = 1,
                prompt = "blood_fire_prompt",
                skill_name = blood_fire.name
            }), Util.IdMapper))
            return #event:getCostData(self) == 1
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local skillTarget = room:getPlayerById(event:getCostData(self)[1])
            local card = room:askToChooseCard(player, {
                target = skillTarget,
                flag = "h",
                skill_name = blood_fire.name
            })
            room:showCards(card, skillTarget)
            local choices = { "blood_fire_damage", "blood_fire_give" }
            local result = room:askToChoice(skillTarget, {
                choices = choices,
                skill_name = blood_fire.name,
                prompt = "blood_fire_prompt_choice"
            })
            if result == "blood_fire_give" then
                room:moveCardTo(card, Card.PlayerHand, player, fk.ReasonGive, blood_fire.name, nil, true, skillTarget)
            elseif result == "blood_fire_damage" then
                room:damage({
                    to = skillTarget,
                    damage = 1,
                    damageType = fk.FireDamage,
                    skillName = blood_fire.name
                })
                if not skillTarget.dead then
                    room:addPlayerMark(skillTarget, "@malice", 1)
                    room:recover({
                        who = skillTarget,
                        num = 1,
                        skillName = blood_fire.name
                    })
                end
            end
        end,
    })
    local malice_eater = fk.CreateSkill {
        name = "malice_eater",
    }
    malice_eater:addEffect(fk.Damaged, {
        anim_type = "offensive",
        can_trigger = function(self, event, target, player, data)
            if not player:hasSkill(malice_eater.name) or player == target or target:getMark("@malice") == 0 then
                return false
            end
            local count = table.sum(player.room:getOtherPlayers(player), function(t)
                return t:getMark("@malice")
            end)
            local choices = 3
            if count < 1 or not player:isWounded() then
                choices = choices - 1
            end
            if count < 2 or target.dead then
                choices = choices - 1
            end
            if count < 3 or target:isNude() then
                choices = choices - 1
            end
            return choices > 0
        end,
        on_cost = function(self, event, target, player, data)
            local room = player.room
            local choices = { "malice_eater_recover", "malice_eater_draw", "malice_eater_discard", "Cancel" }
            local valid = { "malice_eater_recover", "malice_eater_draw", "malice_eater_discard", "Cancel" }
            local count = table.sum(room:getOtherPlayers(player), function(t)
                return t:getMark("@malice")
            end)
            if not player:isWounded() then
                table.removeOne(valid, "malice_eater_recover")
            end
            if count < 2 then
                table.removeOne(choices, "malice_eater_draw")
                table.removeOne(valid, "malice_eater_draw")
            end
            if target.dead then
                table.removeOne(valid, "malice_eater_draw")
            end
            if count < 3 then
                table.removeOne(choices, "malice_eater_discard")
                table.removeOne(valid, "malice_eater_discard")
            end
            if target:isNude() then
                table.removeOne(valid, "malice_eater_discard")
            end
            event:setCostData(self, room:askToChoice(player, {
                choices = valid,
                skill_name = malice_eater.name,
                prompt = "malice_eater_prompt",
                all_choices = choices
            }))
            return event:getCostData(self) ~= "Cancel"
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            if event:getCostData(self) == "malice_eater_recover" then
                local targets = table.filter(room:getOtherPlayers(player), function(t)
                    return t:getMark("@malice") > 0
                end)
                if #targets == 1 then
                    room:removePlayerMark(targets[1], "@malice", 1)
                else
                    room:removePlayerMark(room:askToChoosePlayers(player, {
                        targets = targets,
                        min_num = 1,
                        max_num = 1,
                        prompt = "malice_eater_prompt_chooseOne",
                        skill_name = malice_eater.name
                    }), "@malice", 1)
                end
                room:removePlayerMark(player, "@malice", 1)
                room:recover({
                    who = player,
                    num = 1,
                    skillName = malice_eater.name,
                    recoverBy = player
                })
            elseif event:getCostData(self) == "malice_eater_draw" then
                local targets = table.filter(room:getOtherPlayers(player), function(t)
                    return t:getMark("@malice") > 0
                end)
                if #targets == 1 then
                    room:removePlayerMark(targets[1], "@malice", 2)
                elseif table.sum(targets, function(t)
                        return t:getMark("@malice")
                    end) == 2 then
                    table.forEach(targets, function(t)
                        room:removePlayerMark(t, "@malice", t:getMark("@malice"))
                    end)
                else
                    local remain = 2
                    while remain > 0 do
                        targets = table.filter(room:getOtherPlayers(player), function(t)
                            return t:getMark("@malice") > 0
                        end)
                        local max = math.min(#targets, remain)
                        local select = room:askToChoosePlayers(player, {
                            targets = targets,
                            min_num = 1,
                            max_num = max,
                            prompt = max > 1 and "malice_eater_prompt_choose:::" .. tostring(max) or "malice_eater_prompt_chooseOne",
                            skill_name = malice_eater.name
                        })
                        table.forEach(select, function(t)
                            room:removePlayerMark(t, "@malice", 1)
                        end)
                        remain = remain - #select
                    end
                end
                room:removePlayerMark(player, "@malice", 2)
                room:drawCards(player, 2, malice_eater.name)
                room:loseHp(target, 1, malice_eater.name)
            elseif event:getCostData(self) == "malice_eater_discard" then
                local targets = table.filter(room:getOtherPlayers(player), function(t)
                    return t:getMark("@malice") > 0
                end)
                if #targets == 1 then
                    room:removePlayerMark(targets[1], "@malice", 3)
                elseif table.sum(targets, function(t)
                        return t:getMark("@malice")
                    end) == 3 then
                    table.forEach(targets, function(t)
                        room:removePlayerMark(t, "@malice", t:getMark("@malice"))
                    end)
                else
                    local remain = 3
                    while remain > 0 do
                        targets = table.filter(room:getOtherPlayers(player), function(t)
                            return t:getMark("@malice") > 0
                        end)
                        local max = math.min(#targets, remain)
                        local select = room:askToChoosePlayers(player, {
                            targets = targets,
                            min_num = 1,
                            max_num = max,
                            prompt = max > 1 and "malice_eater_prompt_choose:::" .. tostring(max) or "malice_eater_prompt_chooseOne",
                            skill_name = malice_eater.name
                        })
                        table.forEach(select, function(t)
                            room:removePlayerMark(t, "@malice", 1)
                        end)
                        remain = remain - #select
                    end
                end
                room:removePlayerMark(player, "@malice", 3)
                local cards = target:getCardIds("he")
                room:throwCard(cards, malice_eater.name, target, player)
                local suits = {}
                for _, id in pairs(cards) do
                    local card = Fk:getCardById(id)
                    table.insertIfNeed(suits, card:getSuitString(true))
                end
                if #suits == 1 then
                    room:delay(1000)
                    room:obtainCard(player, cards, true, fk.ReasonPrey, player, malice_eater.name)
                elseif #suits > 1 then
                    local listNames = { "log_spade", "log_club", "log_heart", "log_diamond" }
                    local listCards = { {}, {}, {}, {} }
                    for _, id in ipairs(cards) do
                        local suit = Fk:getCardById(id).suit
                        if suit ~= Card.NoSuit then
                            table.insertIfNeed(listCards[suit], id)
                        end
                    end
                    local result = U.askForChooseCardList(room, player, listNames, listCards, 1, 1, malice_eater.name, "malice_eater_prompt_obtain")[1]
                    room:obtainCard(player, table.filter(cards, function(id)
                        return Fk:getCardById(id):getSuitString(true) == result
                    end), true, fk.ReasonPrey, player, malice_eater.name)
                end
            end
        end,
    })
    extension:loadSkillSkels { blood_fire, malice_eater }
    hy_tenkajin_chiyari:addSkill("blood_fire")
    hy_tenkajin_chiyari:addSkill("malice_eater")
    Fk:loadTranslationTable {
        ["hy_tenkajin_chiyari"] = "天火人血枪",
        ["#hy_tenkajin_chiyari"] = "如怨得火",
        ["illustrator:hy_tenkajin_chiyari"] = "13号",
        ["designer:hy_tenkajin_chiyari"] = "黑曜人形",
        ["cv:hy_tenkajin_chiyari"] = "",

        ["blood_fire"] = "燃血",
        [":blood_fire"] = "你受到伤害或失去体力后或每轮结束时，你可以展示一名其他角色一张手牌并令其选择一项：1.将此牌交给你；2.受到1点火焰伤害，然后回复1点体力并获得1枚“怨”标记。",
        ["blood_fire_prompt"] = "燃血：你可以展示一名其他角色一张手牌",
        ["blood_fire_give"] = "交出牌",
        ["blood_fire_damage"] = "受到伤害",
        ["blood_fire_prompt_choice"] = "燃血：你须选择一项",

        ["malice_eater"] = "食怨",
        [":malice_eater"] = "有“怨”的其他角色受到伤害后，你可以移除场上1至3枚“怨”并执行对应序号项：1.回复1点体力；2.摸两张牌并令其失去1点体力；3.弃置其所有牌，然后你获得其中一种花色的牌。",
        ["@malice"] = "怨",
        ["malice_eater_prompt"] = "食怨：你可以选择一项",
        ["malice_eater_recover"] = "回复1点体力",
        ["malice_eater_draw"] = "摸两张牌",
        ["malice_eater_discard"] = "弃置其所有牌",
        ["malice_eater_prompt_obtain"] = "食怨：获得其中一种花色的牌",
        ["malice_eater_prompt_chooseOne"] = "移除场上1枚“怨”",
        ["malice_eater_prompt_choose"] = "移除场上1至%arg枚“怨”",
    }
end
